﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;

namespace SRTToolsV1
{
    // API请求模型
    public class OllamaRequest
    {
        [JsonPropertyName("model")]
        public string Model { get; set; }

        [JsonPropertyName("prompt")]
        public string Prompt { get; set; }

        [JsonPropertyName("options")]
        public OllamaOptions Options { get; set; } = new OllamaOptions();
    }

    // API请求选项
    public class OllamaOptions
    {
        [JsonPropertyName("temperature")]
        public double Temperature { get; set; } = 0;

        [JsonPropertyName("stop")]
        public List<string> Stop { get; set; } = new List<string> { "\n\n" };
    }

    // API响应模型
    // 定义Ollama流式响应模型
    public class OllamaStreamResponse
    {
        [JsonPropertyName("response")]
        public string Response { get; set; }

        [JsonPropertyName("done")]
        public bool Done { get; set; }

        [JsonPropertyName("done_reason")]
        public string DoneReason { get; set; }
    }

    public class Translator
    {
        private readonly string _model;
        private readonly string _apiUrl;
        private readonly int _chunkSize;
        private readonly HttpClient _httpClient;
        private readonly int _maxWaitTimeMs; // 最大等待时间

        public Translator(string model = "qwen3:14b", string apiUrl = "http://192.168.1.190:11434/api/generate", int maxWaitTimeMs = 30000)
        {
            _model = model;
            _apiUrl = apiUrl;
            _chunkSize = 4000; // 字符分块大小
            _httpClient = new HttpClient();

            _httpClient.Timeout = TimeSpan.FromMilliseconds(maxWaitTimeMs); // 设置超时
            _httpClient.DefaultRequestHeaders.Add("Accept", "text/event-stream");
            _maxWaitTimeMs = maxWaitTimeMs;
        }

        // 智能分割文本
        private List<string> SplitText(string text)
        {
            var chunks = new List<string>();
            for (int i = 0; i < text.Length; i += _chunkSize)
            {
                int end = Math.Min(i + _chunkSize, text.Length);
                if (end < text.Length && !IsPunctuation(text[end]))
                {
                    // 向后寻找合适的分割点（句号、感叹号等）
                    end = text.LastIndexOfAny(new char[] { '.', '!', '?', '。', '！', '？', '\n' }, end - 1);
                    if (end == -1) end = Math.Min(i + _chunkSize, text.Length);
                }
                chunks.Add(text.Substring(i, end - i));
            }
            return chunks;
        }

        // 判断是否为标点符号
        private bool IsPunctuation(char c)
        {
            return c == '.' || c == '!' || c == '?' || c == '。' || c == '！' || c == '？' || c == '\n';
        }

        // 翻译单个文本块
        private async Task<string> TranslateChunkAsync(string chunk, string sourceLang, string targetLang)
        {
            string prompt = $"请将以下{sourceLang}准确翻译成{targetLang}：\n{chunk}";
            var request = new { model = _model, prompt = prompt, stream = true };

            try
            {
                var json = JsonSerializer.Serialize(request);
                var content = new StringContent(json, Encoding.UTF8, "application/json");

                var response = await _httpClient.PostAsync(_apiUrl, content);
                response.EnsureSuccessStatusCode();

                var stream = await response.Content.ReadAsStreamAsync();
                var reader = new StreamReader(stream);

                var fullResponse = new StringBuilder();
                string line;
                bool isDone = false;
                int consecutiveEmptyLines = 0;
                var watch = System.Diagnostics.Stopwatch.StartNew();

                // 循环读取直到完成或超时
                while (!isDone && watch.ElapsedMilliseconds < _maxWaitTimeMs )
                {
                    // 非阻塞读取，设置短超时
                    if (reader.EndOfStream)
                    {
                        await Task.Delay(100); // 短暂等待新数据
                        continue;
                    }

                    line = await reader.ReadLineAsync();

                    if (string.IsNullOrWhiteSpace(line))
                    {
                        consecutiveEmptyLines++;
                        if (consecutiveEmptyLines > 10) break; // 连续空行超过10行视为完成
                        continue;
                    }

                    consecutiveEmptyLines = 0;

                    // 处理data: 前缀
                    if (line.StartsWith("data: "))
                        line = line.Substring(6).Trim();

                    if (line == "[DONE]")
                        break;

                    try
                    {
                        var streamResponse = JsonSerializer.Deserialize<OllamaStreamResponse>(line);
                        if (streamResponse != null)
                        {
                            fullResponse.Append(streamResponse.Response);
                            isDone = streamResponse.Done;

                            // 额外检查完成原因
                            if (isDone && !string.IsNullOrEmpty(streamResponse.DoneReason) &&
                                streamResponse.DoneReason.Equals("stop", StringComparison.OrdinalIgnoreCase))
                            {
                                break;
                            }
                        }
                    }
                    catch (JsonException ex)
                    {
                        Console.WriteLine($"解析行失败: {line}");
                        Console.WriteLine(ex);
                    }
                }

                watch.Stop();
                Console.WriteLine($"翻译耗时: {watch.ElapsedMilliseconds}ms");

                // 处理可能未完成的情况
                if (!isDone && fullResponse.Length > 0)
                {
                    Console.WriteLine("警告: 翻译未完成但已超时，返回当前结果");
                }

                return fullResponse.ToString();
            }
            catch (TaskCanceledException)
            {
                Console.WriteLine("翻译被取消");
                return "[翻译被取消]";
            }
            catch (Exception ex)
            {
                Console.WriteLine($"翻译错误: {ex.Message}");
                return $"[翻译错误: {ex.Message}]";
            }
        }


        public async Task<bool> TranslateStrAsync(StringBuilder inputStr, StringBuilder outputStr, string sourceLang, string targetLang="中文")
        {
            if ((inputStr!=null)&&(outputStr!=null))
            {
                outputStr.Clear();
                if (!string.IsNullOrEmpty(sourceLang))
                    sourceLang = "英语";
                try
                {
                    outputStr.Append(await TranslateChunkAsync(inputStr.ToString(), sourceLang, targetLang));
                    return true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"翻译文件失败: {ex.Message}");
                    return false;
                }
            }
            return false;
        }


        // 翻译文件
        public async Task<bool> TranslateFileAsync(string inputPath, string outputPath, string sourceLang, string targetLang)
        {
            if (!File.Exists(inputPath))
            {
                Console.WriteLine($"文件不存在: {inputPath}");
                return false;
            }

            try
            {
                // 读取文件
                string text = File.ReadAllText(inputPath, Encoding.UTF8);
                var chunks = SplitText(text);
                var translatedChunks = new List<string>();

                Console.WriteLine($"开始翻译，共{chunks.Count}块");
                for (int i = 0; i < chunks.Count; i++)
                {
                    Console.WriteLine($"处理块 {i + 1}/{chunks.Count}...");
                    string translated = await TranslateChunkAsync(chunks[i], sourceLang, targetLang);
                    translatedChunks.Add(translated);
                }

                // 保存翻译结果
                string translatedText = string.Join("", translatedChunks);
                File.WriteAllText(outputPath, translatedText, Encoding.UTF8);

                Console.WriteLine($"翻译完成，保存至: {outputPath}");
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"翻译文件失败: {ex.Message}");
                return false;
            }
        }
    }
}
